package com.cxyd.common.exception;

import com.cxyd.common.Constant;
import com.cxyd.common.RestResponse;
import com.cxyd.common.ResultCode;
import com.google.common.collect.ImmutableMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @Author: huanglianyun
 * @Description:
 * @DATE: Created in 2019/12/20 23:24.
 */
@ControllerAdvice//控制器增强的一个注解
public class ExceptionCatch {

    //一旦捕获到异常,就说明出问题了,记录日志;先定义Logger变量
    private static final Logger LOGGER= LoggerFactory.getLogger(ExceptionCatch.class);

    private static ImmutableMap<Class<? extends Throwable>,RestResponse> EXCEPTIONS;

    protected static ImmutableMap.Builder<Class<? extends Throwable>,RestResponse> builder=ImmutableMap.builder();

    @ExceptionHandler(CustomException.class)
    @ResponseBody//ResponseResult是个对象,所以千万不要忘记了加这个注解.这样才会将java对象转为json格式数据,被页面收到!!
    public RestResponse customException(CustomException customException){

        //记录日志
        LOGGER.error("catch exception:{}",customException.getMessage());

        //通过customException,就可以拿到错误代码
        RestResponse restResponse = customException.getRestResponse();
        //拿到错误代码,就可以返回一个responseresult
        return restResponse;
    }


    //捕获Exception异常
    @ExceptionHandler(Exception.class)
    @ResponseBody//ResponseResult是个对象,所以千万不要忘记了加这个注解.这样才会将java对象转为json格式数据,被页面收到!!
    public RestResponse exception(Exception exception){

        //记录日志
        LOGGER.error("catch exception:{}",exception.getMessage());

        if(EXCEPTIONS == null){
            //说明map还没有构建,
            EXCEPTIONS=builder.build();//EXCEPTIONS构建成功,且不能更改
        }
        //从EXCEPTIONS中找错误类型所对应的错误代码,如果找到了,就将错误代码响应给用户;找不到就响应99999
        RestResponse restResponse = EXCEPTIONS.get(exception.getClass());
        if(restResponse != null){
            //说明在map中,找到了这个异常
            return restResponse;
        }else {
            //不可预知异常,无法获取其错误代码,可统一返回99999
            return new RestResponse(ResultCode.SERVER_ERROR.getCode(),ResultCode.SERVER_ERROR.getMessage(),null);
        }

    }

    //在静态代码块中,用builder构建ImmutableMap
    static {
        //定义异常类型所对应的错误代码
        builder.put(HttpMessageNotReadableException.class,new RestResponse(ResultCode.INVALID_PARAM.getCode(),ResultCode.INVALID_PARAM.getMessage(),null));
    }
}
